home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_08_10 / 8n10122a < prev    next >
Text File  |  1990-08-28  |  18KB  |  552 lines

  1. #include         <alloc.h>
  2. #include         <bios.h>
  3. #include         <dos.h>
  4. #include         <stdio.h>
  5. #include         <stdlib.h>
  6. #include         <string.h>
  7.  
  8. #include         "csimint.h"
  9.  
  10.  
  11. int               start_kb_process(void(*task)(void),int stacksize)
  12.    {
  13.       int   proc_id;
  14.       set_kb_process = 1;
  15.       proc_id = start_process(task,stacksize);
  16.       set_kb_process = 0;
  17.       return(proc_id);
  18.    }
  19.  
  20.  
  21. int               start_process(void(*task)(void),int stacksize)
  22.    {
  23.       char                    *stack;
  24.       struct   _simprocessT   *process;
  25.       int                     *off_seg=(int *)&stack;
  26.       unsigned   int           stackbytes;
  27.       int                      oldinit;
  28.  
  29.       /*  Check to see if tack handler has been installed*/
  30.  
  31.          if(getvect(_INTRPT_)!=task_handler)
  32.             /* if it has not been installed, attempt to */
  33.  
  34.             if(install_handler())
  35.                /* if it doesn't install, report error and exit */
  36.                {
  37.                   printf("error installing task handler \n");
  38.                   exit_processing(1);
  39.                }
  40.  
  41.          if(stacksize > 0x0fdf)
  42.             /* Max stack size in paragraphs (SEGMENT counts)*/
  43.             {
  44.                printf("stack size error: proc id : %d",totalprocs);
  45.                exit_processing(2);
  46.             }
  47.  
  48.          stackbytes = stacksize * 16;
  49.  
  50.       /* Setup Process header and stack */
  51.  
  52.          process =
  53.                (struct _simprocessT *)
  54.                calloc(sizeof(struct _simprocessT) + stackbytes,1);
  55.  
  56.          /* make sure there was enough memory */
  57.          if(process==NULL)
  58.             return(2);
  59.  
  60.          stack = (char *)(process+1);
  61.  
  62.          /* 'Normalize' the bottom of stack pointer, that is
  63.             make sure the offset is less then 16, as would be
  64.             the case if   the program where compiled in the huge
  65.             memory model */
  66.  
  67.          if(off_seg[0]>16)
  68.             for(;off_seg[0]>16;off_seg[1]++,off_seg[0]-=16);
  69.  
  70.          /* remember, the stack actually starts high and
  71.             builds its way down, so put the pointer at the top.*/
  72.  
  73.          stack += stackbytes - 1;
  74.  
  75.          /* finish setup of stack and base pointers */
  76.  
  77.          process->reg_sp = FP_OFF(stack);
  78.          process->reg_ss = FP_SEG(stack);
  79.  
  80.          process->reg_bp = FP_OFF(stack);
  81.  
  82.          process->proc_id = totalprocs++;
  83.          process->init = 1;
  84.  
  85.       /* Setup start jump */
  86.          process->reg_cs = FP_SEG(task);
  87.          process->reg_ip = FP_OFF(task);
  88.  
  89.       /* link into current processes */
  90.          if(processlist==NULL)
  91.             {
  92.                processlist =         process;
  93.                processlist->next =   process;
  94.                processlist->prev =   process;
  95.             }
  96.          else
  97.             {
  98.                process->prev =       processlist;
  99.                process->next =       processlist->next;
  100.                process->next->prev = process;
  101.                processlist->next =   process;
  102.                processlist = process;
  103.             }
  104.          if(set_kb_process)
  105.             kbprocess = processlist;
  106.  
  107.          /* make sure we can get back to where we were... */
  108.          glbl_ss = _SS;
  109.          glbl_sp = _SP;
  110.          glbl_bp = _BP;
  111.          oldinit = _sim_init_val;
  112.  
  113.          /*   tell the task handler what routine the process uses */
  114.  
  115.          glbl_fc = task;
  116.  
  117.          /* tell the task handler that this proc is initing */
  118.  
  119.          _sim_init_val=1;
  120.  
  121.          /* set up the new stak and base pointers and ... */
  122.          _SS = process->reg_ss;
  123.          _SP = process->reg_sp;
  124.          _BP = process->reg_bp;
  125.  
  126.          /* have the task_handle do the rest */
  127.          geninterrupt(_INTRPT_);
  128.  
  129.          _SS = glbl_ss;
  130.          _SP = glbl_sp;
  131.          _BP = glbl_bp;
  132.          glbl_fc = NULL;
  133.          _sim_init_val = oldinit;
  134.          processlist = processlist->prev;
  135.          return(0);
  136.  
  137.    }
  138.  
  139.  
  140. void               stop_process(int   process_id)
  141.    {
  142.       struct   _simprocessT   *process;
  143.       int                      go;
  144.  
  145.       go = 1;
  146.       process = processlist;
  147.  
  148.       while(go)
  149.          {
  150.             if(process_id == process->proc_id)
  151.                {
  152.                   process->status.kill_flag = 1;
  153.                   process->start_time = _sim_system_time;
  154.                   go = 0;
  155.                }
  156.             if(process->next == processlist)
  157.                {
  158.                   if(go)
  159.                      printf("\nattempted to stop non-existant proc\n");
  160.                   go = 0;
  161.                }
  162.             else
  163.                {
  164.                   process = process->next;
  165.                }
  166.          }
  167.    }
  168.  
  169.  
  170.  
  171. void               sim_start(void)
  172.    {
  173.       _sim_init_val=0;
  174.       _last_update_time = *systimer;
  175.       geninterrupt(_INTRPT_);
  176.    }
  177.  
  178.  
  179. void               exit_processing(int condition)
  180.    {
  181.       struct   _simprocessT   *pholder;
  182.       setvect(_INTRPT_,old_vector);
  183.       printf("Exit processing, code : %d\n",condition);
  184.       processlist->prev->next = NULL;
  185.       do
  186.          {
  187.             pholder = processlist;
  188.             processlist = processlist->next;
  189.             free(pholder);
  190.          }   while(processlist!=NULL);
  191.       exit(condition);
  192.    }
  193.  
  194.  
  195. int               install_handler(void)
  196.    {
  197.       void               *new_vector;
  198.  
  199.       _sim_init_val=2;
  200.       old_vector = getvect(_INTRPT_);
  201.       setvect(_INTRPT_,task_handler);
  202.       new_vector = getvect(_INTRPT_);
  203.       if(new_vector==old_vector)
  204.          return(1);
  205.       return(0);
  206.    }
  207.  
  208.  
  209. void   interrupt   task_handler( unsigned bp,unsigned di,unsigned si,
  210.                                  unsigned ds,unsigned es,unsigned dx,
  211.                                  unsigned cx,unsigned bx,unsigned ax,
  212.                                  unsigned ip,unsigned cs,unsigned flags)
  213.    {
  214.       int                    notfound;
  215.       struct   _simprocessT *procpntr;
  216.  
  217.       if(_sim_init_val==2)
  218.          /* if this ever happens, it means that the task handler
  219.             was installed before it should have been, so de-install
  220.             it and stop the program */
  221.          {
  222.             exit_processing(10);
  223.          }
  224.       if(_sim_init_val==0) /* sim_start has been run */
  225.          {
  226.             processlist->reg_bp      = _BP;
  227.             processlist->reg_sp      = _SP;
  228.             processlist->reg_ss      = _SS;
  229.  
  230.             if(processlist->status.kill_flag)
  231.                {
  232.                   if(processlist == kbprocess)
  233.                      /* You can,t kill the kbproc */
  234.                      processlist->status.kill_flag = 0;
  235.                   else
  236.                      {
  237.                         if(processlist->next == processlist)
  238.                            /* no more procs */
  239.                            exit_processing(20);
  240.  
  241.                         /* break list */
  242.                         processlist->prev->next = processlist->next;
  243.  
  244.                         /* move in front of break */
  245.                         processlist = processlist->prev;
  246.  
  247.                         /* free dead proc */
  248.                         free(processlist->next->prev);
  249.  
  250.                         /* fix break */
  251.                         processlist->next->prev = processlist;
  252.                      }
  253.                }
  254.  
  255.             if((kbprocess!= NULL)&&(bioskey(1)))
  256.                processlist = kbprocess;
  257.             else
  258.                {
  259.                   if(_sim_time_ratio != 0.0)
  260.                      {
  261.                         for(notfound = 1;notfound;)
  262.                            {
  263.                               if((kbprocess != NULL)&&(bioskey(1)))
  264.                                  {
  265.                                     processlist = kbprocess;
  266.                                     notfound = 0;
  267.                                  }
  268.                               else
  269.                                  {
  270.                                     processlist = processlist->next;
  271.                                     if((*systimer - _last_update_time)>
  272.